package com.ricchieri.model;

import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@Table(name="reservation")
public class Reservation extends BaseEntity {
	private static final long serialVersionUID = -1809435284584663248L;
	
	@Column(name="cancel", nullable=false)
	private Boolean cancel = Boolean.FALSE;
	
	@Column(name="observation", nullable=true, length=500)
	private String observation;
	
	@Column(name="reservationDate", nullable=false)
	private Date reservationDate;
	
	@Column(name="cost", nullable=true)
	private Double cost;
	
	@OneToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "user", nullable = false)	
	private User user;
	
	@OneToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "operator", nullable = false)	
	private User operator;
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "scheduleCharter", nullable = false, insertable = true, updatable = true)
	private ScheduleCharter scheduleCharter;
	
	@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	@JoinColumn(name = "travel", nullable = true, insertable = true, updatable = true)
	private Travel travel;
	
	@OneToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "reservationType", nullable = false)
	private ReservationType reservationType;
	
	@OneToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "cancelationMotive", nullable = true)
	private CancelationMotive cancelationMotive;
	
	@OneToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "meanPayment", nullable = false)
	private MeanPayment meanPayment;	
	
	@OneToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "passengerType", nullable = false)
	private PassengerType passengerType;	
	
	@Column(name="upOn", nullable=true, length=50)
	private String upOn ;
	
	@Column(name="downOn", nullable=true, length=50)
	private String downOn ;
	
	@Transient 
	private Boolean travelStatus;
	
	@Transient
	private Boolean paymentStatus;

	@Transient
	private int meanPaymentStatusId;
	
	public Boolean getCancel() {
		return cancel;
	}
	public void setCancel(Boolean cancel) {
		this.cancel = cancel;
	}
	public String getObservation() {
		return observation;
	}
	public void setObservation(String observation) {
		this.observation = observation;
	}
	public Date getReservationDate() {
		return reservationDate;
	}
	public void setReservationDate(Date reservationDate) {
		this.reservationDate = reservationDate;
	}
	public Double getCost() {
		return cost;
	}
	public void setCost(Double cost) {
		this.cost = cost;
	}

	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}
	public ScheduleCharter getScheduleCharter() {
		return scheduleCharter;
	}
	public void setScheduleCharter(ScheduleCharter scheduleCharter) {
		this.scheduleCharter = scheduleCharter;
	}
	public Travel getTravel() {
		return travel;
	}
	public void setTravel(Travel travel) {
		this.travel = travel;
	}
	public ReservationType getReservationType() {
		return reservationType;
	}
	public void setReservationType(ReservationType reservationType) {
		this.reservationType = reservationType;
	}
	public User getOperator() {
		return operator;
	}
	public void setOperator(User operator) {
		this.operator = operator;
	}
	public CancelationMotive getCancelationMotive() {
		return cancelationMotive;
	}
	public void setCancelationMotive(CancelationMotive cancelationMotive) {
		this.cancelationMotive = cancelationMotive;
	}
	public MeanPayment getMeanPayment() {
		return meanPayment;
	}
	public void setMeanPayment(MeanPayment meanPayment) {
		this.meanPayment = meanPayment;
	}
	public PassengerType getPassengerType() {
		return passengerType;
	}
	public void setPassengerType(PassengerType passengerType) {
		this.passengerType = passengerType;
	}
	public String getUpOn() {
		return upOn;
	}
	public void setUpOn(String upOn) {
		this.upOn = upOn;
	}
	public String getDownOn() {
		return downOn;
	}
	public void setDownOn(String downOn) {
		this.downOn = downOn;
	}
	
	public Boolean getTravelStatus() {
		return travelStatus;
	}
	
	public Boolean getPaymentStatus() {		
		return paymentStatus;
	}
	
	public void setTravelStatus(Boolean travelStatus) {
		this.travelStatus = travelStatus;
	}
	
	public void setPaymentStatus(Boolean paymentStatus) {
		this.paymentStatus = paymentStatus;
	}
	
	public void changeTravelStatus() {
		if(this.getTravelStatus()) {
			Travel travel = new Travel();
			this.setTravel(travel);
		} else {
			this.setTravel(null);
			if(getPaymentStatus()) {
				setPaymentStatus(Boolean.FALSE);
			}
		}
	}
	
	public void changePaymentStatus() {
		if(this.getPaymentStatus()) {
			if(getTravelStatus()) {
				this.getTravel().setMeanPayment(this.getMeanPayment());
			} else {
				setTravelStatus(Boolean.TRUE);
				changeTravelStatus();
				this.getTravel().setMeanPayment(this.obtainMeanPaymentStatus());
			}
		} else {
			if(getTravelStatus()) {
				this.getTravel().setMeanPayment(null);
			}
		}
	}
	
	public MeanPayment obtainMeanPaymentStatus() {
		if(this.getTravel() != null && this.getTravel().getMeanPayment() != null) {
			return this.getTravel().getMeanPayment();
		} else {
			return this.getMeanPayment();
		}
	}
	
	private Boolean obtainDefaultTravelStatus() {		
		return 	this.getTravel() != null;
	}
	
	private Boolean obtainDefaultPaymentStatus() {		
		return 	this.getTravel() != null && this.getTravel().getMeanPayment() != null;
	}
	
	public int getMeanPaymentStatusId() {
		return meanPaymentStatusId;
	}
	
	public void setMeanPaymentStatusId(int meanPaymentStatusId) {
		this.meanPaymentStatusId = meanPaymentStatusId;
	}

	public void initStatus() {
		meanPaymentStatusId = this.obtainMeanPaymentStatus().getId();
		travelStatus = this.obtainDefaultTravelStatus();
		paymentStatus = this.obtainDefaultPaymentStatus();
	}
	
	public Boolean isTraveled() {
		return travel != null;
	}
}